package com.luyi.sensor.config.datasource;

import com.alibaba.druid.pool.DruidDataSource;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Component
@ConfigurationProperties(prefix = "spring.druid")
@Data
public class DruidProperties {
  /*
    initial-size: 10 # 初始化时建立物理连接的个数。初始化发生在显示调用init方法，或者第一次getConnection时
    min-idle: 10 # 最小连接池数量
    maxActive: 200 # 最大连接池数量
    maxWait: 3000 # 获取连接时最大等待时间，单位毫秒。配置了maxWait之后，缺省启用公平锁，并发效率会有所下降，如果需要可以通过配置
    timeBetweenEvictionRunsMillis: 60000 # 关闭空闲连接的检测时间间隔.Destroy线程会检测连接的间隔时间，如果连接空闲时间大于等于minEvictableIdleTimeMillis则关闭物理连接。
    minEvictableIdleTimeMillis: 300000 # 连接的最小生存时间.连接保持空闲而不被驱逐的最小时间
    testWhileIdle: true # 申请连接时检测空闲时间，根据空闲时间再检测连接是否有效.建议配置为true，不影响性能，并且保证安全性。申请连接的时候检测，如果空闲时间大于timeBetweenEvictionRun
    poolPreparedStatements: true # 开启PSCache
    maxPoolPreparedStatementPerConnectionSize: 20 #设置PSCache值
    connectionErrorRetryAttempts: 3 # 连接出错后再尝试连接三次
    breakAfterAcquireFailure: true # 数据库服务宕机自动重连机制
    timeBetweenConnectErrorMillis: 300000 # 连接出错后重试时间间隔
   */

  /**
   * 初始化时建立物理连接的个数。初始化发生在显示调用init方法，或者第一次getConnection时
   */
  private int initialSize;

  /**
   * 最小连接池数量
   */
  private int minIdle;

  /**
   * 最大连接池数量
   */
  private int maxActive;

  /**
   * 获取连接时最大等待时间，单位毫秒。配置了maxWait之后，缺省启用公平锁，并发效率会有所下降，如果需要可以通过配置
   */
  private int maxWait;

  /**
   * 关闭空闲连接的检测时间间隔.Destroy线程会检测连接的间隔时间，如果连接空闲时间大于等于minEvictableIdleTimeMillis则关闭物理连接。
   */
  private int timeBetweenEvictionRunsMillis;

  /**
   * 连接的最小生存时间.连接保持空闲而不被驱逐的最小时间
   */
  private int minEvictableIdleTimeMillis;

  /**
   * 申请连接时检测空闲时间，根据空闲时间再检测连接是否有效.建议配置为true，不影响性能，并且保证安全性。申请连接的时候检测，如果空闲时间大于timeBetweenEvictionRun
   */
  private boolean testWhileIdle;

  /**
   * 开启PSCache
   */
  private boolean poolPreparedStatements;

  /**
   * 设置PSCache值
   */
  private int maxPoolPreparedStatementPerConnectionSize;

  /**
   * 连接出错后再尝试连接三次
   */
  private int connectionErrorRetryAttempts;

  /**
   * 数据库服务宕机自动重连机制
   */
  private boolean breakAfterAcquireFailure;

  /**
   *  SQL查询,用来验证从连接池取出的连接,在将连接返回给调用者之前.
   *  如果指定,则查询必须是一个SQL SELECT并且必须返回至少一行记录
   *  validation-query: select 1
   */
  private String validationQuery;

  /**
   * 连接出错后重试时间间隔
   */
  private int timeBetweenConnectErrorMillis;

  public DruidDataSource dataSource(String url, String username, String password, String driverClassName) {
    DruidDataSource datasource = new DruidDataSource();
    datasource.setUrl(url);
    datasource.setUsername(username);
    datasource.setPassword(password);
    datasource.setDriverClassName(driverClassName);
    //configuration
    datasource.setInitialSize(initialSize);
    datasource.setMinIdle(minIdle);
    datasource.setMaxActive(maxActive);
    datasource.setMaxWait(maxWait);

    datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
    datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
    datasource.setTestWhileIdle(testWhileIdle);

    datasource.setPoolPreparedStatements(poolPreparedStatements);
    datasource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize);

    datasource.setConnectionErrorRetryAttempts(connectionErrorRetryAttempts);
    datasource.setBreakAfterAcquireFailure(breakAfterAcquireFailure);
    datasource.setTimeBetweenConnectErrorMillis(timeBetweenConnectErrorMillis);
    datasource.setTimeBetweenConnectErrorMillis(timeBetweenConnectErrorMillis);
    return datasource;
  }
}
